﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data;

namespace Check_Printing_Solution
{
    public enum Operations
    {
        Add,
        Update,
        Delete
    }

    public class PrintRunner
    {
        public static bool StopPrint { get; set; }
    }

    public class PrintManager
    {
        EntityModelContainer context = new EntityModelContainer();

        public bool Login( string username, string password )
        {
            var user = from i in context.ApplicationUsers
                       where i.UserName == username && i.Password == password
                       select i;

            if ( user.Count() == 0 )
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public List<Customer> FilterCustomers( string accountnumber )
        {
            var result = from i in context.Customers
                         where i.ChequeNumber.StartsWith( accountnumber ) && i.Enabled == true
                         select i;
            return result.ToList();
        }

        public void AddLayout( TemplateLayout layout )
        {
            context.TemplateLayouts.AddObject( layout );
            context.SaveChanges();
        }

        public void AddChequeType( ChequeType chequetype )
        {
            context.ChequeTypes.AddObject( chequetype );
            context.SaveChanges();
        }

        public void SaveTemplate( TemplateLayout layout, string chequetypeid )
        {
            var result = ( from i in context.TemplateLayouts
                           where i.ChequeTypeId == chequetypeid
                           select i ).FirstOrDefault();

            if ( result != null )
            {
                result.Address1Font = layout.Address1Font;
                result.Address1FontSize = layout.Address1FontSize;
                result.Address1X = layout.Address1X;
                result.Address1Y = layout.Address1Y;

                result.Address2Font = layout.Address2Font;
                result.Address2FontSize = layout.Address2FontSize;
                result.Address2X = layout.Address2X;
                result.Address2Y = layout.Address2Y;

                result.Address3Font = layout.Address3Font;
                result.Address3Size = layout.Address3Size;
                result.Address3X = layout.Address3X;
                result.Address3Y = layout.Address3Y;

                result.Address4Font = layout.Address4Font;
                result.Address4Size = layout.Address4Size;
                result.Address4X = layout.Address4X;
                result.Address4Y = layout.Address4Y;

                result.BankFont = layout.BankFont;
                result.BankFontSize = layout.BankFontSize;
                result.BankX = layout.BankX;
                result.BankY = layout.BankY;
                result.ChequeNumberFont = layout.ChequeNumberFont;
                result.ChequeNumberFontSize = layout.ChequeNumberFontSize;
                result.ChequeNumberX = layout.ChequeNumberX;
                result.ChequeNumberY = layout.ChequeNumberY;
                result.ChquesPerPage = layout.ChquesPerPage;
                result.DepositSlips = layout.DepositSlips;
                result.DistanceBetweenCheques = layout.DistanceBetweenCheques;
                result.NameFont = layout.NameFont;
                result.NameFontSize = layout.NameFontSize;
                result.NameX = layout.NameX;
                result.NameY = layout.NameY;
                result.PrintBranch = layout.PrintBranch;
                result.PrintBranchAddress = layout.PrintBranchAddress;
                result.PrintChequeNos = layout.PrintChequeNos;
                result.PrintCovers = layout.PrintCovers;
                result.PrintNameAddress = layout.PrintNameAddress;
                result.PrintNames = layout.PrintNames;
                result.PrintStubNos = layout.PrintStubNos;

                result.CoverNameFont = layout.CoverNameFont;
                result.CoverNameSize = layout.CoverNameSize;
                result.CoverNameX = layout.CoverNameX;
                result.CoverNameY = layout.CoverNameY;

                result.CoverAddress1Font = layout.CoverAddress1Font;
                result.CoverAddress1Size = layout.CoverAddress1Size;
                result.CoverAddress1X = layout.CoverAddress1X;
                result.CoverAddress1Y = layout.CoverAddress1Y;

                result.CoverAddress2Font = layout.CoverAddress2Font;
                result.CoverAddress2Size = layout.CoverAddress2Size;
                result.CoverAddress2X = layout.CoverAddress2X;
                result.CoverAddress2Y = layout.CoverAddress2Y;

                result.CoverAddress3Font = layout.CoverAddress3Font;
                result.CoverAddress3Size = layout.CoverAddress3Size;
                result.CoverAddress3X = layout.CoverAddress3X;
                result.CoverAddress3Y = layout.CoverAddress3Y;

                result.CoverAddress4Font = layout.CoverAddress4Font;
                result.CoverAddress4Size = layout.CoverAddress4Size;
                result.CoverAddress4X = layout.CoverAddress4X;
                result.CoverAddress4Y = layout.CoverAddress4Y;

                result.CoverTelephoneFont = layout.CoverTelephoneFont;
                result.CoverTelephoneSize = layout.CoverTelephoneSize;
                result.CoverTelephoneX = layout.CoverTelephoneX;
                result.CoverTelephoneY = layout.CoverTelephoneY;

                result.ChequeCountX = layout.ChequeCountX;
                result.ChequeCountY = layout.ChequeCountY;
                result.ChequeNumberFont = layout.ChequeNumberFont;
                result.ChequeNumberFontSize = layout.ChequeNumberFontSize;

                result.CoverCheckNoX = layout.CoverCheckNoX;
                result.CoverCheckNoY = layout.CoverCheckNoY;
                result.CoverCheckNoFont = layout.CoverCheckNoFont;
                result.CoverCheckNoSize = layout.CoverCheckNoSize;

                result.CoverCheckCountX = layout.CoverCheckCountX;
                result.CoverCheckCountY = layout.CoverCheckCountY;
                result.CoverCheckCountFont = layout.CoverCheckCountFont;
                result.CoverCheckCountSize = layout.CoverCheckCountSize;

                result.Landscape = layout.Landscape;

                result.NoChequesPerBook = layout.NoChequesPerBook;
                result.SeqNumberSize = layout.SeqNumberSize;

                result.BoldNameCheque = layout.BoldNameCheque;
                result.BoldNameCover = layout.BoldNameCover;

                result.ChequeCountFontSize = layout.ChequeCountFontSize;

                result.StubX = layout.StubX;
                result.StubY = layout.StubY;
                result.StubFont = layout.StubFont;
                result.StubSize = layout.StubSize;

                result.PrintStubNos2 = layout.PrintStubNos2;

                result.Skip = layout.Skip;

                result.CheckNoCharX = layout.CheckNoCharX;
                result.CheckNoCharY = layout.CheckNoCharY;
                result.CheckNoCharFont = layout.CheckNoCharFont;
                result.CheckNoCharSize = layout.CheckNoCharSize;

                result.CheckNo2X = layout.CheckNo2X;
                result.CheckNo2Y = layout.CheckNo2Y;
                result.CheckNo2Font = layout.CheckNo2Font;
                result.CheckNo2Size = layout.CheckNo2Size;

                result.NoCopies = layout.NoCopies;

                result.CoverCount = layout.CoverCount;

                result.BoldLine2Cheque = layout.BoldLine2Cheque;
                result.BoldLine3Cheque = layout.BoldLine3Cheque;
                result.BoldLine4Cheque = layout.BoldLine4Cheque;
                result.ItalicLine1Cheque = layout.ItalicLine1Cheque;
                result.ItalicLine2Cheque = layout.ItalicLine2Cheque;
                result.ItalicLine3Cheque = layout.ItalicLine3Cheque;
                result.ItalicLine4Cheque = layout.ItalicLine4Cheque;

                result.ItalicLine1Cover = layout.ItalicLine1Cover;
                result.ItalicLine2Cover = layout.ItalicLine2Cover;
                result.ItalicLine3Cover = layout.ItalicLine3Cover;
                result.ItalicLine4Cover = layout.ItalicLine4Cover;

                result.PrintDearCustomer = layout.PrintDearCustomer;

                result.BranchNumberSize = layout.BranchNumberSize;
                result.TransitNumberSize = layout.TransitNumberSize;
                result.AccountNumberSize = layout.AccountNumberSize;
                result.TransitCodeSize = layout.TransitCodeSize;

                result.PaperHeight = layout.PaperHeight;
                result.PaperWidth = layout.PaperWidth;
                result.Tray = layout.Tray;

                context.TemplateLayouts.ApplyCurrentValues( result );
                context.SaveChanges();
            }
            else
            {
                context.TemplateLayouts.AddObject( layout );
                context.SaveChanges();
            }
        }

        public TemplateLayout GetTemplateLayout( string chequetypeid )
        {
            try
            {
                var result = from i in context.TemplateLayouts
                             where i.ChequeTypeId == chequetypeid
                             select i;

                return result.FirstOrDefault();
            }
            catch
            {
                return null;
            }
        }

        public TemplateLayout GetTemplateLayout( string style, string styleid )
        {
            var result = from i in context.ChequeTypes
                         where i.Id == styleid
                         select i.Layouts.FirstOrDefault();

            return result.FirstOrDefault();
        }

        public TemplateLayout GetTemplateLayoutByStyle( string style )
        {
            var result = from i in context.ChequeTypes
                         where i.Name == style
                         select i.Layouts.FirstOrDefault();

            return result.FirstOrDefault();
        }

        public void AddJobLog( JobLog joblog )
        {
            context.JobLogs.AddObject( joblog );
            context.SaveChanges();
        }

        public List<JobLog> GetAllJobLogs( DateTime start, DateTime end, bool showreprints )
        {
            var result = from i in context.JobLogs
                         where EntityFunctions.TruncateTime( i.DatePrinted ) >= EntityFunctions.TruncateTime( start ) &&
                         EntityFunctions.TruncateTime( i.DatePrinted ) <= EntityFunctions.TruncateTime( end ) &&
                         i.IsReprint == showreprints
                         orderby i.DatePrinted descending
                         select i;
            return result.ToList();
        }

        public List<JobLog> GetAllJobLogs( DateTime start, DateTime end, string bank, bool showreprints )
        {
            var result = from i in context.JobLogs
                         where EntityFunctions.TruncateTime( i.DatePrinted ) >= EntityFunctions.TruncateTime( start ) &&
                         EntityFunctions.TruncateTime( i.DatePrinted ) <= EntityFunctions.TruncateTime( end ) &&
                         i.Bank == bank &&
                         i.IsReprint == showreprints
                         orderby i.DatePrinted descending
                         select i;
            return result.ToList();
        }

        public void FlagReprint( bool isreprint, int id )
        {
            var result = ( from i in context.JobLogs
                           where i.Id == id
                           select i ).FirstOrDefault();

            result.IsReprint = isreprint;
            context.SaveChanges();
        }

        public List<Customer> SearchCustomers( string firstname, string lastname, string chequenumber )
        {
            var result = from i in context.Customers
                         where i.Enabled == true
                         select i;

            if ( firstname != string.Empty )
            {
                result = from i in context.Customers
                         where i.FirstName.Contains( firstname )
                         select i;
            }

            if ( lastname != string.Empty )
            {
                result = from i in context.Customers
                         where i.LastName.Contains( lastname )
                         select i;
            }

            if ( chequenumber != string.Empty )
            {
                result = from i in context.Customers
                         where i.ChequeNumber.Contains( chequenumber )
                         select i;
            }

            return result.ToList();
        }

        public List<Customer> GetAllCustomers()
        {
            var result = from i in context.Customers
                         where i.Enabled == true
                         select i;
            return result.ToList();
        }

        public void AddBank( Bank bank )
        {
            context.Banks.AddObject( bank );
            context.SaveChanges();
        }

        public List<Bank> GetAllBanks()
        {
            var result = from i in context.Banks
                         select i;

            return result.ToList();
        }

        public void AddCustomer( Customer customer )
        {
            customer.Enabled = true;
            context.Customers.AddObject( customer );
            context.SaveChanges();
        }

        public List<ChequeType> GetAllChequeTypes()
        {
            var result = from i in context.ChequeTypes
                         orderby i.Name
                         select i;

            return result.ToList();
        }

        public Customer GetCustomer( string id )
        {
            var result = from i in context.Customers
                         where i.Id == id && i.Enabled == true
                         select i;

            return result.FirstOrDefault();
        }

        public List<ApplicationLog> GetLogs()
        {
            var result = from i in context.ApplicationLogs
                         orderby i.EventTime ascending
                         select i;
            return result.ToList();
        }

        public List<ApplicationUser> GetAllUsers()
        {
            var result = from i in context.ApplicationUsers
                         select i;
            return result.ToList();
        }

        public void UpdateCustomer( Customer customer )
        {
            var result = from i in context.Customers
                         where i.Id == customer.Id
                         select i;

            Customer foundcustomer = result.FirstOrDefault();
            foundcustomer.Line2 = customer.Line2;
            foundcustomer.Line3 = customer.Line3;
            foundcustomer.Line4 = customer.Line4;
            foundcustomer.BankId = customer.BankId;
            foundcustomer.ChequeNumber = customer.ChequeNumber;
            foundcustomer.FirstName = customer.FirstName;
            foundcustomer.LastName = customer.LastName;
            foundcustomer.Line1 = customer.Line1;

            context.Customers.ApplyCurrentValues( foundcustomer );
            context.SaveChanges();
        }

        public void DeleteCustomer( string customerid )
        {
            var result = from i in context.Customers
                         where i.Id == customerid
                         select i;

            context.Customers.DeleteObject( result.FirstOrDefault() );
            context.SaveChanges();
        }

        public Bank GetBankById( string bankid )
        {
            var result = from i in context.Banks
                         where i.Id == bankid
                         select i;

            return result.ToList().FirstOrDefault();
        }

        public Bank GetBankByPrefix( string prefix )
        {
            var result = from i in context.Banks
                         where i.BranchPrefix.Contains( prefix )
                         select i;

            return result.ToList().FirstOrDefault();
        }

        internal void UpdateBank( Bank bank )
        {
            var result = from i in context.Banks
                         where i.Id == bank.Id
                         select i;

            Bank savedbank = result.ToList().First();
            savedbank.Name = bank.Name;
            savedbank.ChequeType = bank.ChequeType;
            savedbank.BranchSequence = bank.BranchSequence;
            savedbank.BranchPrefix = bank.BranchPrefix;
            savedbank.BranchCode = bank.BranchCode;
            savedbank.BankAddress = bank.BankAddress;

            context.Banks.ApplyCurrentValues( savedbank );
            context.SaveChanges();
        }

        public void DeleteBank( Bank bank )
        {
            var result = from i in context.Banks
                         where i.Id == bank.Id
                         select i;

            Bank savedbank = result.ToList().First();

            context.Banks.DeleteObject( savedbank );
            context.SaveChanges();
        }

        public void UpdateChequeTypes( ChequeType chequetype )
        {
            var result = ( from i in context.ChequeTypes
                           where i.Id == chequetype.Id
                           select i ).ToList().First();

            result.Name = chequetype.Name;
            result.Description = chequetype.Description;
            result.UseForAll = chequetype.UseForAll;

            context.ChequeTypes.ApplyCurrentValues( result );

            context.SaveChanges();
        }

        public void DeleteChequeType( ChequeType chequetype )
        {
            var templates = ( from i in context.TemplateLayouts
                              where i.ChequeTypeId == chequetype.Id
                              select i ).ToList();

            foreach ( TemplateLayout template in templates )
            {
                context.TemplateLayouts.DeleteObject( template );
            }

            var result = ( from i in context.ChequeTypes
                           where i.Id == chequetype.Id
                           select i ).ToList().First();

            context.ChequeTypes.DeleteObject( result );
            context.SaveChanges();
        }

        public Customer GetCustomerByAccount( string accountnumber )
        {
            var result = ( from i in context.Customers
                           where i.ChequeNumber == accountnumber
                           select i ).FirstOrDefault();

            return result;
        }

        public Bank GetBankByBankCode( string bankcode )
        {
            var result = ( from i in context.Banks
                           where i.BranchPrefix == bankcode
                           select i ).FirstOrDefault();

            return result;
        }

        public DataSet CleanCustomers( DataSet ds )
        {
            for ( int i = 0; i < ds.Tables[ "Customers" ].Rows.Count; i++ )
            {
                if ( ds.Tables[ "Customers" ].Rows[ i ][ 0 ].ToString() == string.Empty )
                {
                    ds.Tables[ "Customers" ].Rows[ i ].Delete();
                }
            }
            ds.Tables[ "Customers" ].AcceptChanges();

            return ds;
        }

        public DataSet CleanBanks( DataSet ds )
        {
            for ( int i = 0; i < ds.Tables[ "Banks" ].Rows.Count; i++ )
            {
                if ( ds.Tables[ "Banks" ].Rows[ i ][ 0 ].ToString() == string.Empty )
                {
                    ds.Tables[ "Banks" ].Rows[ i ].Delete();
                }
            }
            ds.Tables[ "Banks" ].AcceptChanges();

            return ds;
        }

        public List<string> GetAllAccountNumbers()
        {
            var result = ( from i in context.Customers
                           select i.ChequeNumber );

            return result.ToList();
        }

        public List<string> GetAllBranchNumbers()
        {
            var result = ( from i in context.Banks
                           select i.BranchPrefix );

            return result.ToList();
        }

        public void LogApplicationEvent( ApplicationLog appevent )
        {
            context.ApplicationLogs.AddObject( appevent );
            context.SaveChanges();
        }

        public bool DoesCustomerExist( string accountnumber )
        {
            var result = from i in context.Customers
                         where i.ChequeNumber == accountnumber
                         && i.Enabled == true
                         select i;

            if ( result.Count() == 0 )
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public bool BranchExists( string branchid, string branchname )
        {
            var results = 0;

            results = ( from i in context.Banks
                        where i.BranchPrefix == branchid && i.Name == branchname
                        select i ).ToList().Count;

            if ( results == 0 )
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public bool DoesTemplateExist( string chequetype )
        {
            var result = from i in context.ChequeTypes
                         where i.Name == chequetype
                         select i;

            if ( result.Count() == 0 )
            {
                return false;
            }
            else
            {
                if ( result.ToList().First().Layouts.Count == 0 )
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        public void SaveNotes( string accountnumber, string notes )
        {
            var result = from i in context.Customers
                         where i.ChequeNumber == accountnumber
                         select i;

            Customer foundcustomer = result.FirstOrDefault();
            foundcustomer.Ext = notes;

            context.Customers.ApplyCurrentValues( foundcustomer );
            context.SaveChanges();
        }

        public int GetLastChequeNumber( string accountnumber, string branchid, string styleid )
        {
            var result = from i in context.JobLogs
                         where i.CustomerId == accountnumber &&
                         i.Bank == branchid &&
                         i.ChequeTypeId == styleid
                         orderby i.DatePrinted descending
                         select i;

            JobLog joblog = result.FirstOrDefault();
            int lastnumber = 0;

            if ( joblog != null )
            {
                lastnumber = Convert.ToInt32( joblog.LastChequeNumber ) + Convert.ToInt32( joblog.LastQuantity );
            }

            return lastnumber;
        }

        public bool IsRecordInLog( string accountnum, string customername, string filename, string chequetype )
        {
            var result = from i in context.JobLogs
                         where i.Filename == filename
                         && i.CustomerId.Contains( accountnum )
                         && i.ChequeTypeId == chequetype
                         && i.CustomerName == customername
                         select i;
            if ( result.Count() > 0 )
                return true;

            return false;
        }

        public JobLog GetLastLogEntry( string accountnumber, string branchid, string styleid )
        {
            var result = from i in context.JobLogs
                         where i.CustomerId == accountnumber &&
                         i.Bank == branchid &&
                         i.ChequeTypeId == styleid
                         orderby i.DatePrinted descending
                         select i;

            return result.FirstOrDefault();
        }
    }

    public static class Helper
    {
        public static ApplicationUser User { get; set; }
        public static Form MainFormCache { get; set; }
    }
}
